package net.airtheva.uniqueTask4.fragment;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;

import com.mpatric.mp3agic.ID3v1;
import com.mpatric.mp3agic.Mp3File;

import net.airtheva.uniqueTask4.MainActivity;
import net.airtheva.uniqueTask4.Playitem;
import net.airtheva.uniqueTask4.R;
import net.airtheva.uniqueTask4.Utils;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.util.SparseBooleanArray;
import android.view.ActionMode;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnCreateContextMenuListener;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;

public class FileFragment extends Fragment {

	public static final String TAG = "FileFragment";
	
	public static final String KEY_ICON = "icon";
	public static final String KEY_FILENAME = "filename";
	
	public static final int POSITION_PARENT = 0;
	public static final int POSITION_SELF = 1;
	
	class _OnItemClickListener implements OnItemClickListener {
		
		public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
			// TODO Auto-generated method stub
			
			switch(position) {
			case POSITION_PARENT:
				Chdir("..");
				Update();
				break;
			case POSITION_SELF:
				Chdir(".");
				Update();
				break;
			default:
				
				HashMap<String, Object> file = mFiles.get(position);
				int icon = (Integer) file.get(KEY_ICON);
				String filename = (String) file.get(KEY_FILENAME);
				switch(icon) {
				case R.drawable.dir:
					Chdir(filename);
					Update();
					break;
				case R.drawable.music:
					AddAndPlay(file);
					break;
				default:
					Toast.makeText(getActivity(), filename, Toast.LENGTH_SHORT).show();
					break;
				}
				
			}
			
		}
		
	}
	
	class _MultiChoiceModeListener implements AbsListView.MultiChoiceModeListener {

		@Override
		public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
			// TODO Auto-generated method stub
			
			switch(item.getItemId()) {
			case R.id.file_list_view_file_add:
				Add();
				mode.finish();
				break;
			default:
				mode.finish();
				break;
			}
			
			return true;
		}

		@Override
		public boolean onCreateActionMode(ActionMode mode, Menu menu) {
			// TODO Auto-generated method stub
			getActivity().getMenuInflater().inflate(R.menu.file_list_view, menu);
			return true;
		}

		@Override
		public void onDestroyActionMode(ActionMode mode) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
			// TODO Auto-generated method stub
			return false;
		}

		@Override
		public void onItemCheckedStateChanged(ActionMode mode, int position,
				long id, boolean checked) {
			// TODO Auto-generated method stub
			
		}
		
	}
	
	File mCurrentDir;
	
	ListView mFileListView;
	
	ArrayList<HashMap<String, Object>> mFiles;
	SimpleAdapter mAdapter;
	
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		mCurrentDir = Environment.getExternalStorageDirectory();
		
		mFileListView = new ListView(getActivity());
	
		mFileListView.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE_MODAL);
		mFileListView.setOnItemClickListener(new _OnItemClickListener());
		mFileListView.setMultiChoiceModeListener(new _MultiChoiceModeListener());
		// FIXME: Can't set OnKeyListener for ListView in Fragment?
		
		return mFileListView;
	}

	@Override
	public void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
		Setup();
		Update();
	}

	public void Chdir(String path) {
		
		try {

			File newDir = (new File(mCurrentDir, path)).getCanonicalFile();
			mCurrentDir = newDir;
			
			Update();
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	protected ArrayList<HashMap<String, Object>> GetSelectedFiles() {
		
		ArrayList<HashMap<String, Object>> files = new ArrayList<HashMap<String, Object>>();
		
		SparseBooleanArray sba = mFileListView.getCheckedItemPositions();
		int size = sba.size();
		for(int i = 0; i < size; i++) {
			int key = sba.keyAt(i); // i is the index of selected, key is the index of items.
			boolean value = sba.get(key);
			
			if(value) {
				
				HashMap<String, Object> file = mFiles.get(key);
				
				int icon = (Integer) file.get(KEY_ICON);
				
				switch(icon) {
				case R.drawable.file:
				case R.drawable.dir:
				case R.drawable.music:
					files.add(file);
					break;
				}
				
			}
			
		}
		
		return files;
		
	}

	public void Setup() {
		
		String[] source = new String[] {
			"icon",
			"filename"
		};
		
		int[] destination = new int[] {
			R.id.fragment_playing_icon,
			R.id.file_list_view_filename
		};
		
		mFiles = new ArrayList<HashMap<String,Object>>();
		mAdapter = new SimpleAdapter(getActivity(), mFiles, R.layout.file_list_view_item, source, destination);
		mFileListView.setAdapter(mAdapter);
		
	}
	
	public void Update() {
		
		mFiles.clear();
		
		HashMap<String, Object> parent = new HashMap<String, Object>();
		parent.put("icon", R.drawable.dir);
		parent.put("filename", "..");
		mFiles.add(parent);
		
		HashMap<String, Object> self = new HashMap<String, Object>();
		self.put("icon", R.drawable.dir);
		self.put("filename", ".");
		mFiles.add(self);
		
		File[] files = mCurrentDir.listFiles();
		for(int i = 0; i < files.length; i++) {
			
			File file = files[i];
			
			HashMap<String, Object> map = new HashMap<String, Object>();
			if(file.isDirectory()) {
				if(file.canRead()) {
					map.put("icon", R.drawable.dir);
				}
				else {
					map.put("icon", R.drawable.dir_forbidden);
				}
			} else if(file.isFile()) {
				if(file.canRead()) {
					if(Utils.IsAudioFilename(file.getName())) {
						map.put("icon", R.drawable.music);
					}
					else {
						map.put("icon", R.drawable.file);
					}
				}
				else {
					map.put("icon", R.drawable.file_forbidden);
				}
			} else {
				map.put("icon", R.drawable.unknown);
			}
			map.put("filename", file.getName());
			
			mFiles.add(map);
			
		}
		
		mAdapter.notifyDataSetChanged();
		
	}
	
	public void AddAndPlay(HashMap<String, Object> file) {
		
		try {
			
			String filename = (String) file.get(KEY_FILENAME);
			
			Playitem playitem = new Playitem();
			playitem.Title = filename;
			playitem.Uri = "file://" + (new File(mCurrentDir, filename)).getCanonicalPath();
			
			MainActivity mainActivity = (MainActivity) getActivity();
			mainActivity.PlaylistFragment.AddAndPlay(playitem);
			
		} catch(Exception e) {
			
			e.printStackTrace();
			
		}
		
	}
	
	public void Add() {
		
		try {
			
			ArrayList<Playitem> playitems = new ArrayList<Playitem>();
			
			ArrayList<HashMap<String, Object>> files = GetSelectedFiles();
			
			int size = files.size();
			for(int i = 0; i < size; i++) {
				
				Playitem playitem = new Playitem();
				
				HashMap<String, Object> file = files.get(i);
				
				int icon = (Integer) file.get(KEY_ICON);
				if(icon == R.drawable.music) {
					
					String filename = (String) file.get(KEY_FILENAME);
					
					String path = (new File(mCurrentDir, filename)).getCanonicalPath();
					
					Mp3File f = new Mp3File(path);
					
					if(f.hasId3v1Tag()) {
						ID3v1 t = f.getId3v1Tag();
						playitem.Artist = t.getArtist();
						playitem.Album = t.getAlbum();
						playitem.Title = t.getTitle();
					}
					else if(f.hasId3v2Tag()) {
						ID3v1 t = f.getId3v2Tag();
						playitem.Artist = t.getArtist();
						playitem.Album = t.getAlbum();
						playitem.Title = t.getTitle();
					}
					else {
						playitem.Album = mCurrentDir.getName();
					}
					
					playitem.Uri = "file://" + path;
					
					playitems.add(playitem);
					
				}
			}
			
			Utils.GetMainActivity(this).PlaylistFragment.Add(playitems);
			
		} catch(Exception e) {
			
			e.printStackTrace();
			
		}
		
	}
	
}
